﻿using System.Collections.ObjectModel;
using System.Diagnostics;
using SoonCode.FocusTest.Models;
using Flurl.Http;
using Newtonsoft.Json;
using SoonCode.Core;
using HandyControl.Controls;
using static AutoMapper.Internal.ExpressionFactory;

namespace SoonCode.FocusTest.Api
{
    public static class API
    {
        public static readonly string Host = "http://focus.soonmake.com/";
         //public static readonly string Host = "http://192.168.0.104:3000/";


        public static readonly string BaseUrl = Host + "service";
        public static int timeout = 30;

        // private static readonly string BaseUrl = "http://192.168.0.101:8000";
        public static async Task<ObservableCollection<TeacherModel>> GetTeacherList(string orgId)
        {
            try
            {
                string url = BaseUrl + "/focus-service/device/teacherList?orgId=" + orgId;
                var res = await url.WithTimeout(timeout).WithOAuthBearerToken(GlobalModel.Token).GetJsonAsync<ObservableCollection<TeacherModel>>();
                return res;
            }
            catch (Exception ex)
            {
                showException(ex);
                return new ObservableCollection<TeacherModel>();
            }
        }
        public static async Task<ObservableCollection<AppsModel>> getApps()
        {
            try
            {
                string url = Host + "apps.json";
                var res = await url.WithTimeout(timeout).GetJsonAsync<ObservableCollection<AppsModel>>();
                return res;
            }
            catch (Exception ex)
            {
                showException(ex);
                return new ObservableCollection<AppsModel>();
            }
        }
        public static async Task<bool> SaveOrgCustomInfo(Dictionary<string,object> dict)
        {
            try
            {
                string url = BaseUrl + "/focus-service/device/customInfo";
                await url.WithTimeout(30).WithOAuthBearerToken(GlobalModel.Token)
                    .AppendQueryParam(dict).PutAsync();
                return true;
            }
            catch (Exception e)
            {
                showException(e);
                return false;
            }
        }
        public static async Task<bool> SaveFee(FeeInfo fee)
        {
            try
            {
                string url = BaseUrl + "/focus-service/device/fee";
                var requset = url.WithTimeout(30).WithOAuthBearerToken(GlobalModel.Token);
                if (fee.id.IsNullOrEmpty())
                {
                    await requset.PostUrlEncodedAsync(fee);
                }
                else
                {
                    await requset.AppendQueryParam(fee).PutAsync();
                }

                return true;
            }
            catch (Exception ex)
            {
                showException(ex);
                return false;
            }
        }

        public static async Task<bool> DeleteFee(string id)
        {
            try
            {
                string url = BaseUrl + "/focus-service/device/fee?ids=" + id;
                await url.WithTimeout(timeout).WithOAuthBearerToken(GlobalModel.Token).DeleteAsync();
                return true;
            }
            catch (Exception ex)
            {
                showException(ex);
                return false;
            }
        }

        public static async Task<ObservableCollection<FeeInfo>> GetFeeList(string memberId)
        {
            try
            {
                string url = BaseUrl + "/focus-service/device/fees?pageSize=1000&pageIndex=1&memberId=" + memberId;
                var res = await url.WithTimeout(timeout).WithOAuthBearerToken(GlobalModel.Token).GetJsonAsync<Dictionary<string, Object>>();
                return JsonConvert.DeserializeObject<ObservableCollection<FeeInfo>>(res["content"].ToString());
            }
            catch (Exception ex)
            {
                showException(ex);
                return new ObservableCollection<FeeInfo>();
            }
        }

        public static async Task<Dictionary<string, string>> SubmitTest(TestInfo testInfo)
        {
            try
            {
                string url = BaseUrl + "/focus-service/device/postMemberTest";
                var res = await url.WithTimeout(timeout).WithOAuthBearerToken(GlobalModel.Token).PostJsonAsync(testInfo)
                    .ReceiveJson<Dictionary<string, Object>>();
                if (res["code"].ToString() == "0000")
                {
                    return JsonConvert.DeserializeObject<Dictionary<string, string>>(res["data"].ToString());
                }
                else if (res["desc"] != null)
                {
                    throw new APIException(res["desc"].ToString());
                }
                else
                {
                    throw new APIException("提交失败，请重试！");
                }
            }
            catch (Exception ex)
            {
                showException(ex);
                return null;
            }
        }

        public static async Task<OrgInfo> GetCurrOrg()
        {
            try
            {
                string url = BaseUrl + "/focus-service/device/currOrg";
                var res = await url.WithTimeout(timeout).WithOAuthBearerToken(GlobalModel.Token).GetJsonAsync<OrgInfo>();
                return res;
            }
            catch (Exception ex)
            {
                showException(ex);
                return null;
            }
        }

        public static async Task<ObservableCollection<MemberInfo>> GetMemberList(Dictionary<string, object> where)
        {
            try
            {
                if (where == null) where = new Dictionary<string, object>();
                string url = BaseUrl + "/focus-service/device/getMemberList";
                var res = await url.WithTimeout(timeout).WithOAuthBearerToken(GlobalModel.Token).PostUrlEncodedAsync(
                    where).ReceiveJson<Dictionary<string, Object>>();
                if (res["code"].ToString() == "0000")
                {
                    return JsonConvert.DeserializeObject<ObservableCollection<MemberInfo>>(res["data"].ToString());
                }
                else if (res["desc"] != null)
                {
                    throw new APIException(res["desc"].ToString());
                }
                else
                {
                    throw new APIException("请求错误：" + res["code"]);
                }
            }
            catch (Exception ex)
            {
                showException(ex);
                return null;
            }
        }

        public static async Task<ObservableCollection<ClassesInfo>> GetClasses(string orgId)
        {
            try
            {
                string url = BaseUrl + "/focus-service/classes/classList?orgId=" + orgId;
                var res = await url.WithTimeout(timeout).WithOAuthBearerToken(GlobalModel.Token)
                    .GetJsonAsync<ObservableCollection<ClassesInfo>>();
                return res;
            }
            catch (Exception ex)
            {
                showException(ex);
                return new ObservableCollection<ClassesInfo>();
            }
        }

        public static async Task<ObservableCollection<DictModel>> GetStatuses()
        {
            try
            {
                string url = BaseUrl + "/focus-service/member/statuses";
                var res = await url.WithTimeout(timeout).WithOAuthBearerToken(GlobalModel.Token)
                    .GetJsonAsync<ObservableCollection<DictModel>>();
                return res;
            }
            catch (Exception ex)
            {
                showException(ex);
                return new ObservableCollection<DictModel>();
            }
        }

        public static async Task<ObservableCollection<DictModel>> GetChannels()
        {
            try
            {
                string url = BaseUrl + "/focus-service/member/channels";
                var res = await url.WithTimeout(timeout).WithOAuthBearerToken(GlobalModel.Token)
                    .GetJsonAsync<ObservableCollection<DictModel>>();
                return res;
            }
            catch (Exception ex)
            {
                showException(ex);
                return new ObservableCollection<DictModel>();
            }
        }

        public static async Task<bool> DeleteMember(string memberId)
        {
            try
            {
                string url = BaseUrl + "/focus-service/device/member?ids=" + memberId;
                await url.WithTimeout(timeout).WithOAuthBearerToken(GlobalModel.Token).DeleteAsync();
                return true;
            }
            catch (Exception ex)
            {
                showException(ex);
                return false;
            }
        }

        public static async Task<bool> SaveMember(MemberInfo data)
        {
            try
            {
                string url = BaseUrl + "/focus-service/device/member";
                var request = url.WithTimeout(timeout).WithOAuthBearerToken(GlobalModel.Token);
                if (data.id.IsNullOrEmpty())
                    await request.PostUrlEncodedAsync(data);
                else
                    await request.AppendQueryParam(data).PutAsync();
                return true;
            }
            catch (Exception ex)
            {
                showException(ex);
                return false;
            }
        }

        public static async Task<UserInfo> Login(string username, string password, string mac)
        {
            try
            {
                string url = BaseUrl + "/focus-service/device/publicApi/login";
                var res = await url.WithTimeout(timeout).PostUrlEncodedAsync(new { account = username, password = password, mac = mac })
                    .ReceiveJson<Dictionary<string, Object>>();
                if (res["code"].ToString() == "0000")
                {
                    UserInfo user = new UserInfo()
                    {
                        Account = username,
                        Id = res["userId"].ToString(),
                        Name = res["name"].ToString(),
                        Token =
                            JsonConvert.DeserializeObject<Dictionary<string, Object>>(res["jwt"].ToString())[
                                "access_token"].ToString()
                    };
                    return user;
                }
                else if (res["desc"] != null)
                {
                    throw new APIException(res["desc"].ToString());
                }
                else
                {
                    throw new APIException("用户登录失败，请检查用户名是否正确！");
                }
            }
            catch (Exception ex)
            {
                showException(ex);
                return null;
            }
        }

        public static void showException(Exception ex)
        {
            FileHelper.WriteLog(ex.Message, DateTime.Now.ToString("yyyy-MM-dd") + ".log");
            FileHelper.WriteLog(ex.StackTrace, DateTime.Now.ToString("yyyy-MM-dd") + ".log");
            if (ex is APIException)
            {
                Growl.Error(ex.Message);
            }
            else if (ex is FlurlHttpException)
            {
                FlurlHttpException httpException = ex as FlurlHttpException;
                if (httpException.StatusCode == null)
                    Growl.ErrorGlobal("连接服务器失败，请检查网络！");
                else if(httpException.StatusCode==400)
                    Growl.ErrorGlobal("请求失败：参数错误");
                else if(httpException.StatusCode == 401)
                    Growl.ErrorGlobal("服务器认证失败，请重新登录");
                else if(httpException.StatusCode == 404)
                    Growl.ErrorGlobal("请求失败，服务不存在，请稍后再试！");
                else if (httpException.StatusCode == 503)
                    Growl.ErrorGlobal("请求失败，服务维护中，请稍后再试！");
                else Growl.ErrorGlobal($"服务错误：{httpException.StatusCode}，请与提供商联系!");
            }
            else
            {
                Growl.ErrorGlobal("错误：" + ex.Message);
            }
        }
    }
}